# -*- coding: utf-8 -*-
"""
企业微信推送模块
负责通过企业微信发送告警消息
"""

import json
import time
import requests
from typing import Dict, Any, List, Optional
from common.logger import get_logger
from common.config import config

logger = get_logger(__name__)


class WeChatPusher:
    """企业微信推送器"""
    
    def __init__(self):
        """初始化企业微信推送器"""
        self.webhook_url = config.get('wechat.webhook_url', '')
        self.secret = config.get('wechat.secret', '')
        self.access_token = None
        self.token_expires_at = 0
        
        if not self.webhook_url:
            logger.warning("企业微信webhook URL未配置")
    
    def get_access_token(self) -> Optional[str]:
        """
        获取访问令牌
        
        Returns:
            访问令牌
        """
        if not self.secret:
            return None
        
        # 检查令牌是否过期
        current_time = time.time()
        if self.access_token and current_time < self.token_expires_at:
            return self.access_token
        
        try:
            # 获取访问令牌
            token_url = f"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={self.secret}&corpsecret={self.secret}"
            response = requests.get(token_url, timeout=10)
            
            if response.status_code == 200:
                data = response.json()
                if data.get('errcode') == 0:
                    self.access_token = data.get('access_token')
                    self.token_expires_at = current_time + data.get('expires_in', 7200) - 300  # 提前5分钟过期
                    logger.info("成功获取企业微信访问令牌")
                    return self.access_token
                else:
                    logger.error(f"获取企业微信访问令牌失败: {data.get('errmsg')}")
            else:
                logger.error(f"获取企业微信访问令牌请求失败: {response.status_code}")
                
        except Exception as e:
            logger.error(f"获取企业微信访问令牌异常: {e}")
        
        return None
    
    def send_text_message(self, content: str, mentioned_list: List[str] = None) -> bool:
        """
        发送文本消息
        
        Args:
            content: 消息内容
            mentioned_list: 提及用户列表
            
        Returns:
            是否发送成功
        """
        if not self.webhook_url:
            logger.error("企业微信webhook URL未配置")
            return False
        
        try:
            message = {
                "msgtype": "text",
                "text": {
                    "content": content
                }
            }
            
            if mentioned_list:
                message["text"]["mentioned_list"] = mentioned_list
            
            response = requests.post(
                self.webhook_url,
                json=message,
                timeout=10,
                headers={'Content-Type': 'application/json'}
            )
            
            if response.status_code == 200:
                result = response.json()
                if result.get('errcode') == 0:
                    logger.info("企业微信文本消息发送成功")
                    return True
                else:
                    logger.error(f"企业微信文本消息发送失败: {result.get('errmsg')}")
            else:
                logger.error(f"企业微信文本消息请求失败: {response.status_code}")
                
        except Exception as e:
            logger.error(f"发送企业微信文本消息异常: {e}")
        
        return False
    
    def send_markdown_message(self, content: str) -> bool:
        """
        发送Markdown消息
        
        Args:
            content: Markdown内容
            
        Returns:
            是否发送成功
        """
        if not self.webhook_url:
            logger.error("企业微信webhook URL未配置")
            return False
        
        try:
            message = {
                "msgtype": "markdown",
                "markdown": {
                    "content": content
                }
            }
            
            response = requests.post(
                self.webhook_url,
                json=message,
                timeout=10,
                headers={'Content-Type': 'application/json'}
            )
            
            if response.status_code == 200:
                result = response.json()
                if result.get('errcode') == 0:
                    logger.info("企业微信Markdown消息发送成功")
                    return True
                else:
                    logger.error(f"企业微信Markdown消息发送失败: {result.get('errmsg')}")
            else:
                logger.error(f"企业微信Markdown消息请求失败: {response.status_code}")
                
        except Exception as e:
            logger.error(f"发送企业微信Markdown消息异常: {e}")
        
        return False
    
    def send_alarm_message(self, alarm_data: Dict[str, Any]) -> bool:
        """
        发送告警消息
        
        Args:
            alarm_data: 告警数据
            
        Returns:
            是否发送成功
        """
        try:
            # 构建告警消息
            log_data = alarm_data.get('log_data', {})
            strategy = alarm_data.get('strategy', {})
            
            # 构建Markdown内容
            markdown_content = self._build_alarm_markdown(log_data, strategy)
            
            # 发送Markdown消息
            return self.send_markdown_message(markdown_content)
            
        except Exception as e:
            logger.error(f"发送告警消息失败: {e}")
            return False
    
    def _build_alarm_markdown(self, log_data: Dict[str, Any], strategy: Dict[str, Any]) -> str:
        """
        构建告警Markdown内容
        
        Args:
            log_data: 日志数据
            strategy: 策略数据
            
        Returns:
            Markdown内容
        """
        try:
            content = f"""## 🚨 日志告警通知

### 策略信息
- **策略名称**: {strategy.get('name', '未知')}
- **策略描述**: {strategy.get('description', '无')}

### 日志信息
- **应用名称**: {log_data.get('app_name', '未知')}
- **日志级别**: {log_data.get('level', '未知')}
- **主机**: {log_data.get('host', '未知')}
- **时间**: {log_data.get('timestamp', '未知')}

### 日志内容
```
{log_data.get('message', '无内容')}
```

### 告警时间
{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}

---
*此消息由日志分析系统自动发送*"""
            
            return content
            
        except Exception as e:
            logger.error(f"构建告警Markdown内容失败: {e}")
            return f"告警消息构建失败: {str(e)}"
    
    def send_batch_alarm_messages(self, alarm_list: List[Dict[str, Any]]) -> Dict[str, int]:
        """
        批量发送告警消息
        
        Args:
            alarm_list: 告警列表
            
        Returns:
            发送结果统计
        """
        success_count = 0
        failed_count = 0
        
        for alarm_data in alarm_list:
            try:
                if self.send_alarm_message(alarm_data):
                    success_count += 1
                else:
                    failed_count += 1
                
                # 添加延迟避免发送过快
                time.sleep(0.5)
                
            except Exception as e:
                logger.error(f"批量发送告警消息失败: {e}")
                failed_count += 1
        
        result = {
            'success_count': success_count,
            'failed_count': failed_count,
            'total_count': len(alarm_list)
        }
        
        logger.info(f"批量发送告警消息完成: {result}")
        return result
    
    def test_connection(self) -> bool:
        """
        测试连接
        
        Returns:
            连接是否正常
        """
        if not self.webhook_url:
            return False
        
        try:
            test_message = {
                "msgtype": "text",
                "text": {
                    "content": "测试消息 - 日志分析系统连接测试"
                }
            }
            
            response = requests.post(
                self.webhook_url,
                json=test_message,
                timeout=10,
                headers={'Content-Type': 'application/json'}
            )
            
            if response.status_code == 200:
                result = response.json()
                return result.get('errcode') == 0
            else:
                return False
                
        except Exception:
            return False
    
    def get_config_info(self) -> Dict[str, Any]:
        """
        获取配置信息
        
        Returns:
            配置信息
        """
        return {
            'webhook_url': self.webhook_url,
            'secret_configured': bool(self.secret),
            'connection_status': self.test_connection()
        } 